#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "../include/datatype/NcMap.h"

// 性能测试配置
#define TEST_SIZE_SMALL     1000      // 小规模测试
#define TEST_SIZE_MEDIUM    10000     // 中等规模测试  
#define TEST_SIZE_LARGE     100000    // 大规模测试

// 生成测试键
void generate_test_key(char* buffer, int index) {
    sprintf(buffer, "test_key_%d", index);
}

// 插入性能测试
double test_insert_performance(int test_size) {
    printf("测试插入性能 - 数据量: %d\n", test_size);
    
    NcMapHandle map = NcMapCreate();
    if (!map) {
        printf("创建Map失败\n");
        return 0.0;
    }
    
    char key_buffer[32];
    clock_t start = clock();
    
    // 执行插入操作
    for (int i = 0; i < test_size; i++) {
        generate_test_key(key_buffer, i);
        NcMapSetInt(map, key_buffer, i * 10);
    }
    
    clock_t end = clock();
    double time_taken = ((double)(end - start)) / CLOCKS_PER_SEC;
    
    printf("插入 %d 个元素耗时: %.4f 秒\n", test_size, time_taken);
    printf("平均每个元素插入时间: %.6f 秒\n", time_taken / test_size);
    printf("插入速度: %.0f 元素/秒\n\n", test_size / time_taken);
    
    NcMapDestroy(map);
    return time_taken;
}

// 查询性能测试
double test_lookup_performance(int test_size) {
    printf("测试查询性能 - 数据量: %d\n", test_size);
    
    NcMapHandle map = NcMapCreate();
    if (!map) {
        printf("创建Map失败\n");
        return 0.0;
    }
    
    char key_buffer[32];
    
    // 先插入测试数据
    for (int i = 0; i < test_size; i++) {
        generate_test_key(key_buffer, i);
        NcMapSetInt(map, key_buffer, i * 10);
    }
    
    printf("数据准备完成，开始查询测试...\n");
    
    clock_t start = clock();
    int found_count = 0;
    int result;
    
    // 执行查询操作（查询所有键）
    for (int i = 0; i < test_size; i++) {
        generate_test_key(key_buffer, i);
        if (NcMapGetInt(map, key_buffer, &result)) {
            found_count++;
        }
    }
    
    clock_t end = clock();
    double time_taken = ((double)(end - start)) / CLOCKS_PER_SEC;
    
    printf("查询 %d 个元素耗时: %.4f 秒\n", test_size, time_taken);
    printf("成功找到: %d 个元素\n", found_count);
    printf("平均每个元素查询时间: %.6f 秒\n", time_taken / test_size);
    printf("查询速度: %.0f 元素/秒\n\n", test_size / time_taken);
    
    NcMapDestroy(map);
    return time_taken;
}

// 混合操作性能测试
double test_mixed_performance(int test_size) {
    printf("测试混合操作性能 - 数据量: %d\n", test_size);
    
    NcMapHandle map = NcMapCreate();
    if (!map) {
        printf("创建Map失败\n");
        return 0.0;
    }
    
    char key_buffer[32];
    clock_t start = clock();
    
    // 混合操作：插入、查询、更新、删除
    for (int i = 0; i < test_size; i++) {
        generate_test_key(key_buffer, i);
        
        // 插入
        NcMapSetInt(map, key_buffer, i);
        
        // 查询
        int result;
        NcMapGetInt(map, key_buffer, &result);
        
        // 更新
        if (i % 2 == 0) {
            NcMapSetInt(map, key_buffer, i * 2);
        }
        
        // 删除部分数据
        if (i % 10 == 9) {
            generate_test_key(key_buffer, i - 5);
            NcMapRemove(map, key_buffer);
        }
    }
    
    clock_t end = clock();
    double time_taken = ((double)(end - start)) / CLOCKS_PER_SEC;
    
    printf("混合操作 %d 轮耗时: %.4f 秒\n", test_size, time_taken);
    printf("最终Map大小: %d\n", NcMapSize(map));
    printf("平均每轮操作时间: %.6f 秒\n", time_taken / test_size);
    printf("操作速度: %.0f 轮/秒\n\n", test_size / time_taken);
    
    NcMapDestroy(map);
    return time_taken;
}

// 内存使用测试
void test_memory_usage(int test_size) {
    printf("测试内存使用 - 数据量: %d\n", test_size);
    
    NcMapHandle map = NcMapCreate();
    if (!map) {
        printf("创建Map失败\n");
        return;
    }
    
    char key_buffer[32];
    char value_buffer[64];
    
    // 插入不同类型的数据
    for (int i = 0; i < test_size; i++) {
        generate_test_key(key_buffer, i);
        
        if (i % 3 == 0) {
            // 整数
            NcMapSetInt(map, key_buffer, i);
        } else if (i % 3 == 1) {
            // 小数
            double value = i * 1.5;
            NcMapSetDouble(map, key_buffer, &value);
        } else {
            // 字符串
            sprintf(value_buffer, "value_%d_string", i);
            NcMapSetString(map, key_buffer, value_buffer);
        }
    }
    
    printf("成功插入 %d 个混合类型元素\n", test_size);
    printf("Map大小: %d\n", NcMapSize(map));
    
    // 测试获取所有键
    const char* keys = NcMapGetKeys(map);
    if (keys) {
        int key_count = 0;
        const char* ptr = keys;
        while (*ptr) {
            if (*ptr == ';') key_count++;
            ptr++;
        }
        key_count++; // 最后一个键
        printf("获取到 %d 个键\n", key_count);
    }
    
    printf("内存测试完成\n\n");
    NcMapDestroy(map);
}

// 哈希冲突测试
void test_hash_collision(void) {
    printf("测试哈希冲突处理\n");
    
    NcMapHandle map = NcMapCreate();
    if (!map) {
        printf("创建Map失败\n");
        return;
    }
    
    // 插入一些可能产生冲突的键
    const char* test_keys[] = {
        "abc", "bac", "cab",  // 相同字符不同顺序
        "test1", "test2", "test3",
        "key_a", "key_b", "key_c",
        "hash_collision_test_1",
        "hash_collision_test_2",
        "hash_collision_test_3",
        NULL
    };
    
    // 插入测试数据
    for (int i = 0; test_keys[i] != NULL; i++) {
        NcMapSetInt(map, test_keys[i], i * 100);
    }
    
    printf("插入了 %d 个测试键\n", NcMapSize(map));
    
    // 验证所有数据都能正确检索
    int success_count = 0;
    for (int i = 0; test_keys[i] != NULL; i++) {
        int result;
        if (NcMapGetInt(map, test_keys[i], &result)) {
            if (result == i * 100) {
                success_count++;
            } else {
                printf("数据错误: 键 '%s' 期望值 %d, 实际值 %d\n", 
                       test_keys[i], i * 100, result);
            }
        } else {
            printf("查找失败: 键 '%s'\n", test_keys[i]);
        }
    }
    
    printf("成功验证 %d 个键的数据完整性\n", success_count);
    printf("哈希冲突测试完成\n\n");
    
    NcMapDestroy(map);
}

int main() {
    printf("=== NcMap 高性能哈希表测试 ===\n\n");
    
    // 哈希冲突测试
    test_hash_collision();
    
    // 内存使用测试
    test_memory_usage(TEST_SIZE_SMALL);
    
    // 性能测试
    printf("=== 性能基准测试 ===\n\n");
    
    // 小规模测试
    printf("--- 小规模测试 (%d 元素) ---\n", TEST_SIZE_SMALL);
    test_insert_performance(TEST_SIZE_SMALL);
    test_lookup_performance(TEST_SIZE_SMALL);
    test_mixed_performance(TEST_SIZE_SMALL);
    
    // 中等规模测试
    printf("--- 中等规模测试 (%d 元素) ---\n", TEST_SIZE_MEDIUM);
    test_insert_performance(TEST_SIZE_MEDIUM);
    test_lookup_performance(TEST_SIZE_MEDIUM);
    test_mixed_performance(TEST_SIZE_MEDIUM);
    
    // 大规模测试
    printf("--- 大规模测试 (%d 元素) ---\n", TEST_SIZE_LARGE);
    test_insert_performance(TEST_SIZE_LARGE);
    test_lookup_performance(TEST_SIZE_LARGE);
    test_mixed_performance(TEST_SIZE_LARGE);
    
    printf("=== 所有性能测试完成 ===\n");
    printf("\n性能总结:\n");
    printf("- 使用哈希表实现，平均时间复杂度 O(1)\n");
    printf("- 自动扩容机制，负载因子控制在 %.2f\n", 0.75);
    printf("- 支持混合数据类型存储\n");
    printf("- 内存使用高效，按需分配\n");
    
    return 0;
} 